package com.ethan.base;

import java.lang.reflect.*;

/**
 * @author ethan
 * create 2018-07-27 下午9:11
 * desc
 **/
public class ReflectTest {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //1.通过类名获取Class对象
        //Class<People> peopleClass = People.class;

        //2.通过对象本身获取Class对象
        //People people = new People("张三",20);
        //Class<People> peopleClass2 = (Class<People>) people.getClass();

        //3.通过反射获取类的构造器
        /**
        Class<People> peopleClass = People.class;
        Constructor<People> constructor = peopleClass.getConstructor(String.class, int.class);
        // 设置 constructor 的 Accessible属性为ture以取消Java的访问检查
        constructor.setAccessible(true);
        People people =  constructor.newInstance("哈哈",30);
        people.speak();
         **/

        //4.通过反射获取类中定义的方法
        /**
        Student student = new Student();
        student.setName("李四");
        student.setAge(25);
        student.setGrade(1);

        Method[] methods = student.getClass().getDeclaredMethods();
        for (Method method:methods) {
            System.out.println("declared method name : " + method.getName());
        }


        try {
            //获取learnMethod对象（封装了learn方法）
            Method learnMethod = student.getClass().getDeclaredMethod("learn", String.class);
            //获取learn方法的参数列表并打印出来
            Class<?>[] paramClasses = learnMethod.getParameterTypes() ;
            for (Class<?> item : paramClasses) {
                System.out.println("learn方法的参数: " + item.getName());
            }
            //判断learn方法是否为private
            System.out.println(learnMethod.getName() + " is private "
                    + Modifier.isPrivate(learnMethod.getModifiers()));
            learnMethod.invoke(student, "Java Reflection");
        } catch (Exception e) {
            e.printStackTrace();
        }**/

        //5.通过反射获取类中定义的属性
        showDeclaredFields();

        //通过反射获取类的父类及类所实现的接口
//        showInterfaces();


       String a ="";
    }

    private static void showDeclaredFields() {
        Student student = new Student();
        student.setName("bill");
        student.setAge(18);
        // 获取当前类中定义的所有属性并显示出来
        Field[] publicFields = student.getClass().getFields();
        for (Field field : publicFields) {
            if(!field.isAccessible()){
                field.setAccessible(true);
            }
            System.out.println("declared field name : " + field.getName());
        }

        try {
            // 获取指定的属性
            Field gradeField = student.getClass().getDeclaredField("grade");
            // 获取属性值
            System.out.println("The grade is : " + gradeField.getInt(student));
            // 设置属性值
            gradeField.set(student, 10);
            System.out.println("The grade is : " + gradeField.getInt(student));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void showInterfaces() {
        Student student = new Student();
        student.setName("bill");
        student.setAge(18);
        Class<?>[] interfaces = student.getClass().getInterfaces();
        for (Class<?> item: interfaces) {
            System.out.println("Implements interface: " + item.getName());
        }
    }
}
